/**
 * Copyright (C) 2025 pony working team
 * SPDX-License-Identifier: MulanPSL-2.0
 */

/* define to prevent recursive inclusion -------------------------------------*/
#ifndef __K_OBJ_H__
#define __K_OBJ_H__

/* includes (standard library, system) ---------------------------------------*/
#include <stdint.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdbool.h>

#include <sys/fcntl.h>
/* includes (other library) --------------------------------------------------*/
/* includes (project) --------------------------------------------------------*/
#include <x_atomic.h>
#include <x_list.h>
#include <x_module.h>
/* includes (local) ----------------------------------------------------------*/
#include "k_errno.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/* defines -------------------------------------------------------------------*/

#define OBJ_FLAGS_STATIC 1 /* object is static, should not be freed */
#define OBJ_FLAGS_EXCL   2 /* opened as O_EXCL */

#define ERRNO_OBJ_ILLEGAL_ID        ERRNO_JOIN(MID_OBJ, 1)
#define ERRNO_OBJ_ILLEGAL_MAGIC     ERRNO_JOIN(MID_OBJ, 2)
#define ERRNO_OBJ_ILLEGAL_CLASS     ERRNO_JOIN(MID_OBJ, 3)
#define ERRNO_OBJ_ILLEGAL_OPERATION ERRNO_JOIN(MID_OBJ, 4)
#define ERRNO_OBJ_STILL_USING       ERRNO_JOIN(MID_OBJ, 5)

/* typedefs ------------------------------------------------------------------*/

typedef struct cls *cls_id;

typedef struct obj {
    uintptr_t magic;      /* magic, (uintptr_t) self */
    atomic_uint safe_cnt; /* protect for deleting */
    atomic_uint open_cnt; /* open (reference) count */
    unsigned int flags;   /* flags */
    cls_id cls;           /* class id this object belongs to */
    dlist_t node;         /* used to link into class->objs */
    void *task_del;       /* task wanna delete this object */
    const char *name;
} obj_t, *obj_id;

typedef int (*obj_foreach_pfn)(obj_id o, va_list va);

/* macro ---------------------------------------------------------------------*/
/* inlines -------------------------------------------------------------------*/
/* externs -------------------------------------------------------------------*/

extern int obj_verify(cls_id c, obj_id o);
extern int obj_verify_protect(cls_id c, obj_id o);
extern void obj_unprotect(obj_id o);
extern int obj_init(cls_id c, obj_id o, ...);
extern obj_id obj_create(cls_id c, ...);
extern obj_id obj_open(cls_id c, const char *name, int oflag, va_list va);
extern int obj_destroy(cls_id c, obj_id);
extern obj_id obj_foreach(cls_id c, obj_foreach_pfn foreach_rtn, ...);
extern obj_id obj_find(cls_id c, const char *name);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* __K_OBJ_H__ */
